package com.dsbj.mp.icardservice.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.dsbj.common.msg.ResponseMessage;
import com.dsbj.mp.icardservice.entity.*;
import com.dsbj.mp.icardservice.feign.WxApiFeign;
import com.dsbj.mp.icardservice.model.FunctionModel;
import com.dsbj.mp.icardservice.model.MenuModel;
import com.dsbj.mp.icardservice.model.MenuModelGroup;
import com.dsbj.mp.icardservice.model.MpUser;
import com.dsbj.mp.icardservice.service.physicalcondition.SecurityGuardsService;
import com.dsbj.mp.icardservice.utils.Constants;
import com.dsbj.mp.icardservice.utils.PropertyUtil;
import com.dsbj.mp.icardservice.utils.strprocess.StrUtil;
import com.dsbj.mp.icardservice.webserviceclient.dsbjpmc.AllowUserResponseMessage;
import com.dsbj.mp.icardservice.webserviceclient.dsbjpmc.JWSService;
import com.dsbj.mp.icardservice.webserviceclient.dsbjpmc.WxUser;
import com.dsbj.mp.icardservice.webserviceclient.dsbjpmc.WxUserResponseMessage;
import com.dsbj.starter.redis.utils.MultiRedisHelper;
import com.dsbj.starter.redis.utils.RedisHelper;
import com.netflix.discovery.converters.Auto;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class WxUserService {

	public static Logger logger= LoggerFactory.getLogger(WxUserService.class);

	@Autowired
	private JWSService jwsService;

	@Autowired
	private EmployeeService employeeService;

	@Autowired
	private PersontService persontService;

    @Autowired
    private EmployeeWelfareService employeeWelfareService;

	@Autowired
	private MultiRedisHelper multiRedisHelper;

	@Autowired
	private SecurityGuardsService securityGuardsService;

	@Inject
	private WxApiFeign wxApiFeign;

	@Autowired
	private MpUserRoleService mpUserRoleService;

	@Autowired
	private MpResourceService mpResourceService;

	@Autowired
	private MpRoleResourceService mpRoleResourceService;

	@Autowired
	private EmployeeWorkStatusService employeeWorkStatusService;

	/*@Resource(name = "httpsRestTemplate")
	private RestTemplate httpsRestTemplate;*/


	public ResponseMessage wxBindUser(Integer type, String openId, String username, String password, String employeeNo, String phoneNo, String vCode) {
		//若type为0，绑定类型为"一卡通用户绑定"
		if(type.equals(0)){
			return wxBindICardUser(openId,username,password);
		}else{
			//若type为1，绑定类型为"普通员工绑定"
			return wxBindEmployee(openId,employeeNo,phoneNo,vCode);
		}
	}

	private ResponseMessage wxBindEmployee(String openId, String employeeNo, String phoneNo, String vCode) {

		/**
		 * 验证客户填入的验证码(vCode)是否正确
		 */
		String vCodeReal=(String)multiRedisHelper.get(Constants.WX_BIND_VCODE_PREFIX +phoneNo,Constants.REDISDB_VCODE);
		if(StrUtil.isEmpty(vCodeReal)||!vCodeReal.equals(vCode)){
			return ResponseMessage.error("验证码错误，请重新获取验证码!");
		}

		//根据手机号查询员工,检查员工工号和填写的工号是否一致
		Employee employee = (Employee) employeeService.getEmployeeByPhoneNum(phoneNo).getData();
		if(employee==null){
			return ResponseMessage.error("用户手机号不存在");
		}
		if(!StringUtils.equals(employeeNo,employee.getEmployeeno())){
			return ResponseMessage.error("工号不一致");
		}

		AllowUserResponseMessage msg = jwsService.getUserByEmployeeno(employeeNo);
		if(!msg.isSuccess()){
			return ResponseMessage.error(msg.getMessage());
		}
		if(msg.getAllowUser()!=null){
			//校验公司编号是否一致
			if(!StringUtils.equals(employee.getCompanyno(),msg.getAllowUser().getCompanyno())){
				return ResponseMessage.error("公司编号不一致,请联系后台管理人员");
			}
		}
		msg = jwsService.wxBindUser(openId,msg.getAllowUser().getEmployeeNo());
		if(msg.isSuccess()){
			return ResponseMessage.ok();
		}else{
			return ResponseMessage.error(msg.getMessage());
		}
	}

	private ResponseMessage wxBindICardUser(String openId, String username, String password) {
		AllowUserResponseMessage msg = jwsService.getUserByUsernameAndPassWord(username,password);
		if(!msg.isSuccess()||msg.getAllowUser()==null||StringUtils.isBlank(msg.getAllowUser().getEmployeeNo())){
			return ResponseMessage.error(msg.getMessage());
		}
		//通过工号查询员工,校验companyno是否一致
		Employee employee = employeeService.getEmployeeByNo(msg.getAllowUser().getEmployeeNo());
		if(employee!=null&&!employee.getCompanyno().equals(msg.getAllowUser().getCompanyno())){
			return ResponseMessage.error("公司编号不一致,请联系后台管理人员");
		}

		msg = jwsService.wxBindUser(openId,msg.getAllowUser().getEmployeeNo());
		if(msg.isSuccess()){
			return ResponseMessage.ok();
		}else{
			return ResponseMessage.error(msg.getMessage());
		}
	}

	/**
	 *
	 * @deprecated 待删
	 * @param openId
	 * @return
	 */
	@Deprecated
	public WxUserResponseMessage getWxUserByOpenId(String openId) {
		WxUserResponseMessage msg = jwsService.getWxUserByOpenId(openId);

		if(!msg.isSuccess()||msg.getWxUser()==null){
			return msg;
		}

		///根据工号查普通员工
		WxUser wxUser = msg.getWxUser();
		Employee employee = employeeService.getEmployeeByNo(wxUser.getEmployeeNo());

		if(wxUser.getLevel().equals(0)){
			//0表示不是一卡通用户，需要判断是否是普通用户
			if(employee==null){
				msg.setSuccess(false);
				msg.setMessage("用户不存在");
				return msg;
			}else{
				wxUser.setDeptno(employee.getDeptno());
				wxUser.setCompanyno(employee.getCompanyno());
				wxUser.setName(employee.getEmployeename());
				wxUser.setSex(employee.getSex());
			}
		}else{
			if(employee!=null){
				wxUser.setLevel(2);
				wxUser.setDeptno(employee.getDeptno());
			}
		}

		return msg;
	}


	public ResponseMessage getOpenIdByCode(String code) {
		/*if(StringUtils.isBlank(code)){
			return ResponseMessage.error("code不能为空");
		}
		String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", PropertyUtil.getAppid(),PropertyUtil.getAppsecret(),code);
		Map<String,String> map = new HashMap<>();
		map = httpsRestTemplate.getForObject(url,HashMap.class);
		String openId = map.get("openid");
		if(StringUtils.isBlank(openId)){
			return ResponseMessage.error("获取openid失败");
		}
		return ResponseMessage.ok(openId);*/

		logger.info("getOpenIdByCode: code="+code);
		return wxApiFeign.getOpenIdByCode(code);
	}

	/**
	 * 微信用户绑定V2.0。
	 * 将openId和idcardno进行绑定,并向该用户分配"普通员工角色"。
	 *
	 * @param openId
	 * @param idNo
	 * @param phoneNo
	 * @param vCode
	 * @return
	 */
	public ResponseMessage mpBindUser(String openId, String idNo, String phoneNo, String vCode) {

		/**
		 * 特殊流程》微信审核使用
		 */
		/**/
		String wxChecker_idNo = "123456789012345678";
		String wxChecker_phoneNo = "12345678901";
		String wxChecker_vCode = "123456";
		Boolean wxCheckerUse = wxChecker_idNo.equals(idNo) && wxChecker_phoneNo.equals(phoneNo) && wxChecker_vCode.equals(vCode);
		if (wxCheckerUse == true) {
			//直接进行用户绑定
			AllowUserResponseMessage msg = jwsService.wxBindUserByOpenIdAndIdcardno(openId, idNo);
			if (msg.isSuccess() == false) {
				return ResponseMessage.error(msg.getMessage());
			}
			//向该用户分配"普通员工角色"
			mpUserRoleService.assignRoleToCommonEmployee(wxChecker_idNo);
			return ResponseMessage.ok();
		}


		/**
		 * 正常验证流程》检查身份证号,手机号信息。
		 * 查询了h_p_employee, h_p_persont两张表。
		 */
		//查询h_p_employee表是否包含该身份证号(排除离职状态)
		QueryWrapper<Employee> queryWrapper_employee = new QueryWrapper<Employee>()
				.eq("IDCARDNO", idNo)
				.isNull("DISMISSIONDATE")
				.eq("DELETESTATUS", 1);
		Employee employee = employeeService.getOne(queryWrapper_employee);

		if (employee == null) {
			//人员档案没有该身份证,附加人员信息表取
			QueryWrapper<Persont> queryWrapper_persont = new QueryWrapper<Persont>()
					.eq("IDCARDNO", idNo)
					.eq("STATUS", 1);
			Persont persont = persontService.getOne(queryWrapper_persont);
			if (persont == null) {
				return ResponseMessage.error("没有该身份证用户");
			}
			//校验手机号是否一致
			if (StringUtils.isBlank(persont.getPhoneNumber())) {
				return ResponseMessage.error("手机号不存在");
			}
			if (!persont.getPhoneNumber().equals(phoneNo)) {
				return ResponseMessage.error("手机号和人员档案中的手机号不一致!");
			}
		} else {
			/**
			 * h_p_employee表中含有该员工信息,从附加信息表查出手机号,并检验是否一致。
			 */
			QueryWrapper<EmployeeWelfare> queryWrapper_employeeWelfare = new QueryWrapper<EmployeeWelfare>()
					.eq("EMPLOYEENO", employee.getEmployeeno());
			EmployeeWelfare employeeWelfare = employeeWelfareService.getOne(queryWrapper_employeeWelfare);
			if (null == employeeWelfare) {
				return ResponseMessage.error("人员附加信息不存在");
			}
			if (StringUtils.isBlank(employeeWelfare.getContactway())) {
				return ResponseMessage.error("手机号不存在");
			}
			if (!employeeWelfare.getContactway().equals(phoneNo)) {
				return ResponseMessage.error("手机号和人员档案中的手机号不一致!");
			}
		}

		/**
		 * 验证客户填入的验证码(vCode)是否正确
		 */
		String vCodeReal = (String) multiRedisHelper.get(Constants.WX_BIND_VCODE_PREFIX + phoneNo, Constants.REDISDB_VCODE);
		if (StrUtil.isEmpty(vCodeReal) || !vCodeReal.equals(vCode)) {
			return ResponseMessage.error("验证码错误,请重新获取验证码!");
		}

		/**
		 * 将openId和idcardno进行绑定,并向该用户分配"普通员工角色"。
		 */
		AllowUserResponseMessage msg = jwsService.wxBindUserByOpenIdAndIdcardno(openId, idNo);
		if (msg.isSuccess() == false) {
			return ResponseMessage.error(msg.getMessage());
		}
		//向该用户分配"普通员工角色"
		mpUserRoleService.assignRoleToCommonEmployee(idNo);
		return ResponseMessage.ok();
	}

	/**
	 * 根据openId获取用户信息V2.0。
	 * @param openId
	 * @return
	 */
	public ResponseMessage getMpUserByOpenId(String openId) {

		//请求jws获取wxUser
		WxUserResponseMessage msg = jwsService.getIdcardnoByOpenId(openId);
		if(!msg.isSuccess()||msg.getWxUser()==null){
			return ResponseMessage.error(501,"");
		}

		//将wxUser中的信息存入mpUser中
		WxUser wxUser=msg.getWxUser();
		MpUser mpUser = new MpUser();
		BeanCopier beanCopier =BeanCopier.create(WxUser.class, MpUser.class, false);
		beanCopier.copy(wxUser,mpUser,null);

		/**
		 * 特殊流程》微信审核使用
		 */
		/**/
		{
			String idcardno = mpUser.getIdcardno();
			String wxChecker_idcardno = "123456789012345678";
			if (wxChecker_idcardno.equals(idcardno)) {
				//填充wxUser对象
				mpUser.setLevel(2);
				mpUser.setCompanyno("01-07");
				mpUser.setDeptno("010701");
				mpUser.setEmployeeNo("D501900993");
				mpUser.setSex("男");
				mpUser.setName("微信小程序审核人员");
				//
				return ResponseMessage.ok(mpUser);
			}
		}

		/**
		 * 正常流程》根据工号查询员工信息。
		 * 从h_p_persont,h_p_employee两张表中查询该用户信息。
		 */
		QueryWrapper<Persont> queryWrapper_persont=new QueryWrapper<Persont>()
				.eq("IDCARDNO",mpUser.getIdcardno())
				.eq("STATUS",1);
		Persont persont=persontService.getOne(queryWrapper_persont);
		//若persont为null
		if(persont==null){
			QueryWrapper<Employee> queryWrapper_employee=new QueryWrapper<Employee>()
					.eq("IDCARDNO",mpUser.getIdcardno())
					.isNull("DISMISSIONDATE")
					.eq("DELETESTATUS",1);
			Employee employee= employeeService.getOne(queryWrapper_employee);
			if(employee==null){
				return ResponseMessage.error("该用户不存在");
			}
			//将employee中的信息存入mpUser中。
			mpUser.setLevel(2);
			mpUser.setCompanyno(employee.getCompanyno());
			mpUser.setDeptno(employee.getDeptno());
			mpUser.setEmployeeNo(employee.getEmployeeno());
			mpUser.setIdcardno(employee.getIdcardno());
			mpUser.setSex(employee.getSex());
			mpUser.setName(employee.getEmployeename());

		}else{
			/**
			 * 若persont含有信息
			 */
			mpUser.setLevel(3);
			mpUser.setCompanyno(persont.getCompanyno());
			//mpUser.setDeptno(persont.getDeptno());
			mpUser.setEmployeeNo(persont.getEmployeeno());
			mpUser.setIdcardno(persont.getIdcardno());
			mpUser.setSex(persont.getSex());
			mpUser.setName(persont.getEmployeename());
		}

		//判断当前用户是否是保安
		QueryWrapper<SecurityGuards> queryWrapper_securityGuards=new QueryWrapper<SecurityGuards>()
				.eq("IDCARDNO",wxUser.getIdcardno())
				.eq("STATUS",1);
		SecurityGuards securityGuards = securityGuardsService.getOne(queryWrapper_securityGuards);
		if(null != securityGuards){
			mpUser.setLevel(4);
		}

		return ResponseMessage.ok(mpUser);
	}

	/**
	 * 根据idcardNo获取该用户可操作的功能列表。
	 * @param idcardNo
	 * @return
	 */
	public List<MenuModelGroup> getFunctionModelsByIdcardNo(String idcardNo) {

		List<String> roleIds = mpUserRoleService.list(new QueryWrapper<MpUserRole>().eq("IDCARDNO",idcardNo)).stream().map(y->y.getRoleId()).collect(Collectors.toList());
		if(CollectionUtils.isNotEmpty(roleIds)){
			List<String> resourceIds = mpRoleResourceService.list(new QueryWrapper<MpRoleResource>().in("ROLE_ID",roleIds) ).stream().map(x->x.getResourceId()).collect(Collectors.toList());
			if(CollectionUtils.isNotEmpty(resourceIds)){
				List<MpResource> list = mpResourceService.list(new QueryWrapper<MpResource>().in("id",resourceIds) );
				if(CollectionUtils.isNotEmpty(list)){
					return list.stream()
							.map(x->new MenuModel(x.getName(),x.getPath(),x.getIcon(),x.getCategory()))
							.collect(Collectors.groupingBy(MenuModel::getCategory))
							.entrySet().stream()
							.map(entry->new MenuModelGroup(entry.getKey(),entry.getValue()))
							.collect(Collectors.toList());
				}
			}

		}

		return new ArrayList<>();
	}
}
